package com.event.common.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import java.util.List;

/**
 * @Description sql解析工具
 * @Author Bing
 * @Date 2024/10/17 10:02
 */
public class SqlParseUtil {
    /**
     * 查询增删改指定列的值
     * @param statement
     * @param columnName
     * @return
     */
    public static String getUpdateValue(Statement statement, String columnName) {
        if(statement instanceof Insert){
            return getColumnInsertValue((Insert)statement,columnName);
        }else if(statement instanceof Update){
            return getColumnUpdateValue((Update)statement,columnName);
        }else if(statement instanceof Delete){
            return getColumnDeleteValue((Delete)statement,columnName);
        }
        return null;
    }

    /**
     * 查询插入语句中指定列的值
     * @param insert
     * @param columnName
     * @return
     */
    private static String getColumnInsertValue(Insert insert, String columnName) {
        // 处理DuplicateUpdate类型的插入语句
        List<Column> duplicateColumns = insert.getDuplicateUpdateColumns();
        List<Expression> expressionList = insert.getDuplicateUpdateExpressionList();
        if(CollUtil.isNotEmpty(duplicateColumns) && CollUtil.isNotEmpty(expressionList)){
            int index = findIndex(duplicateColumns, columnName);
            if(index > 0 && expressionList.size() > index){
                return expressionList.get(index).toString();
            }
        }
        // 处理普通插入语句
        int index = findIndex(insert.getColumns(), columnName);
        if(index < 0){
            return null;
        }
        ExpressionList itemsList = insert.getItemsList(ExpressionList.class);
        if(ObjectUtil.isNull(itemsList)){
            return null;
        }
        List<Expression> expressions = itemsList.getExpressions();
        if(CollUtil.isEmpty(expressions)){
            return null;
        }
        if(expressions.size() < index){
            return null;
        }
        return expressions.get(index).toString();
    }

    /**
     * 查询更新语句中指定列的值
     * @param update
     * @param columnName
     * @return
     */
    private static String getColumnUpdateValue(Update update, String columnName) {
        // 先查询条件
        Expression where = update.getWhere();
        if(ObjectUtil.isNotNull(where) && where instanceof EqualsTo){
            EqualsTo equalsTo = (EqualsTo) where;
            if (equalsTo.getLeftExpression() instanceof Column && ((Column) equalsTo.getLeftExpression()).getColumnName().equals(columnName)) {
                return equalsTo.getRightExpression().toString();
            }
        }
        // 再查更新项
        for (UpdateSet updateSet : update.getUpdateSets()) {
            List<Column> columns = updateSet.getColumns();
            List<Expression> expressionList = updateSet.getExpressions();
            int index = findIndex(columns, columnName);
            if(index < 0){
                continue;
            }
            if(expressionList.size() < index){
                continue;
            }
            return updateSet.getExpressions().get(index).toString();
        }
        return null;
    }

    /**
     * 查询指定列在列表中的索引
     * @param columns
     * @param columnName
     * @return
     */
    private static int findIndex(List<Column> columns, String columnName) {
        for(int i = 0 ; i < columns.size() ; i++){
            Column column =  columns.get(i);
            if(column.getColumnName().equals(columnName)){
                return i;
            }
        }
        return -1;
    }

    /**
     * 查询删除语句中指定列的值
     * @param delete
     * @param columnName
     * @return
     */
    private static String getColumnDeleteValue(Delete delete, String columnName) {
        Expression where = delete.getWhere();
        if (ObjectUtil.isNotNull(where) && where instanceof EqualsTo) {
            EqualsTo equalsTo = (EqualsTo) where;
            if (equalsTo.getLeftExpression() instanceof Column && ((Column) equalsTo.getLeftExpression()).getColumnName().equals(columnName)) {
                return equalsTo.getRightExpression().toString();
            }
        }
        return null;
    }
}